import { app, shell, BrowserWindow, screen } from 'electron'
import icon from '../../../resources/icon.png?asset'
import { is } from '@electron-toolkit/utils'
import { join } from 'path'
import { spawn } from 'child_process';
import BaseWindow from './components/BaseWindow'
import store from '../store/index';

export default class AiIconWindow extends BaseWindow {
  private x = 0
  private y = 0

  initialX = 0
  initialY = 0
  winW = 0
  winH = 0
  constructor() {
    super()
    const { width: screenW, height: screenH } = screen.getPrimaryDisplay().workAreaSize
    this.x = screenW - 500
    this.y = screenH - 500
  }
  //创建窗口
  create(): void {
    if (this.frame !== null && !this.frame.isDestroyed()) return
    // 创建窗口
    this.frame = new BrowserWindow({
      width: 60,
      height: 60,
      x: this.x,
      y: this.y,
      show: false,
      transparent: true, // 窗口背景透明 默认值为false
      alwaysOnTop: true, // 窗口置顶 默认值为false
      autoHideMenuBar: true, // 隐藏菜单栏 默认值为false
      resizable: false, // 禁止调整窗口大小 默认值为true
      hasShadow: false, // 禁止窗口阴影 默认值为true
      skipTaskbar: true, // 隐藏任务栏 默认值为false
      icon, // 如果是linux系统，设置窗口图标
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'), // 预加载脚本
        sandbox: false, // 禁用沙箱模式
        zoomFactor: 1.0 // 禁止缩放
      }
    })

    // 窗口准备显示时，显示窗口
    this.frame.on('ready-to-show', () => {
      this.frame!.show()
    })

    // 监听窗口显示之后置顶
    this.frame!.on('show', () => {
      setTimeout(() => {
        this.frame!.setSkipTaskbar(true); // 隐藏任务栏
        this.setAsTop() // 置顶
        if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
          this.frame!.webContents.send('current-network-is-intranet', true) // 开发环境，默认是内网
        } else {
          this.frame!.webContents.send('current-network-is-intranet', store.get('isIntranet')) // 发送当前网络是否是内网
        }
      }, 500)
    });
    // 失去焦点时，发送消息
    this.frame!.on('blur', () => {
      this.frame!.webContents.send('aiicon-window-blur') // 发送窗口失去焦点
      // console.log('失去焦点')
      this.setAsTop() // 置顶
    })
    // focus 窗口时，发送消息
    this.frame!.on('focus', () => {
      // console.log('获得焦点')
    })

    // 设置窗口打开链接的处理方式
    this.frame.webContents.setWindowOpenHandler((details) => {
      shell.openExternal(details.url) // 打开外部链接使用默认浏览器
      return { action: 'deny' }
    })

    // 加载路由页面
    const routerPath = '/aiAssistant'
    if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
      this.frame.loadURL(process.env['ELECTRON_RENDERER_URL'] + '/#' + routerPath)
    } else {
      this.frame.loadFile(join(__dirname, '../renderer/index.html'), {
        hash: routerPath
      })
    }
  }

  // 置顶
  setAsTop () {
    this.frame?.setAlwaysOnTop(true, 'screen-saver');
  }

  // 拖拽窗口
  startDrag () {
    const point = screen.getCursorScreenPoint()
    const bounds = this.frame!.getContentBounds()
    this.initialX = point.x - bounds.x
    this.initialY = point.y - bounds.y
    this.winW = bounds.width
    this.winH = bounds.height
  }
  moveDrag(): void {
    const point = screen.getCursorScreenPoint()
    let x = point.x - this.initialX
    let y = point.y - this.initialY

    // 计算所有屏幕组成的大矩形区域
    const allDisplays = screen.getAllDisplays()
    let screenBounds = allDisplays.reduce((acc, display) => {
      const bounds = display.bounds
      acc.minX = Math.min(acc.minX, bounds.x)
      acc.maxX = Math.max(acc.maxX, bounds.x + bounds.width)
      acc.minY = Math.min(acc.minY, bounds.y)
      acc.maxY = Math.max(acc.maxY, bounds.y + bounds.height)
      return acc
    }, {
      minX: Infinity,
      maxX: -Infinity,
      minY: Infinity,
      maxY: -Infinity,
    })

    // 获取当前鼠标所在屏幕
    const currentDisplay = screen.getDisplayNearestPoint({ x, y })
    const workArea = currentDisplay.workArea

    const mouseRange = { minX: 0, maxX: 0, minY: 0, maxY: 0 } // 所有窗口的范围
    mouseRange.minX = screenBounds.minX
    mouseRange.maxX = screenBounds.maxX
    mouseRange.minY = workArea.y
    mouseRange.maxY = workArea.height + workArea.y

    // 限制窗口不能拖出所有屏幕的边界
    if (x < mouseRange.minX) x = mouseRange.minX
    if (x + this.winW > mouseRange.maxX) x = mouseRange.maxX - this.winW

    if (y < mouseRange.minY) y = mouseRange.minY
    if (y + this.winH > mouseRange.maxY) y = mouseRange.maxY - this.winH

    // 设置窗口位置
    this.frame?.setBounds({ x, y, width: 60, height: 60 })

    this.frame?.webContents.send('window-position-updated', { x, y, mouseRange, winW: this.winW, winH: this.winH })
  }
  stopDrag () {

  }

  // 刷新位置
  refreshPosition (x, y) {
    // 计算所有屏幕组成的大矩形区域
    const allDisplays = screen.getAllDisplays()
    let screenBounds = allDisplays.reduce((acc, display) => {
      const bounds = display.bounds
      acc.minX = Math.min(acc.minX, bounds.x)
      acc.maxX = Math.max(acc.maxX, bounds.x + bounds.width)
      acc.minY = Math.min(acc.minY, bounds.y)
      acc.maxY = Math.max(acc.maxY, bounds.y + bounds.height)
      return acc
    }, {
      minX: Infinity,
      maxX: -Infinity,
      minY: Infinity,
      maxY: -Infinity,
    })

    // 获取当前鼠标所在屏幕
    const currentDisplay = screen.getDisplayNearestPoint({ x, y })
    const workArea = currentDisplay.workArea

    const mouseRange = { minX: 0, maxX: 0, minY: 0, maxY: 0 } // 所有窗口的范围
    mouseRange.minX = screenBounds.minX
    mouseRange.maxX = screenBounds.maxX
    mouseRange.minY = workArea.y
    mouseRange.maxY = workArea.height + workArea.y

    this.frame?.setBounds({ x, y, width: 60, height: 60 })
    this.frame?.webContents.send('window-position-updated', { x, y, mouseRange, winW: this.winW, winH: this.winH })
  }

  // 触发截图
  async triggerScreenshot () {
    // this.hideAiIconWindow()
    const exePath = this.getExePath();
    const child = spawn(exePath);
    child.on("close", (_code) => {
      // when code is:
      // 0 undefined
      // 1 按关闭按钮退出btn;
      // 2 按鼠标右键退出btn;
      // 3 按esc键退出;
      // 4 复制rgb颜色时退出;
      // 5 复制十六进制颜色时退出;
      // 6 复制cmyk颜色时退出;
      // 7 复制鼠标位置时退出;
      // 8 保存到文件时退出;
      // 9 保存到剪贴板时退出;
    });
  }

  // 获取ScreenCapture.exe路径
  getExePath() {
    if (app.isPackaged) {
      return join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'ScreenCapture.exe');
    } else {
      return join(process.cwd(), 'resources', 'ScreenCapture.exe');
    }
  }
}
